package com.bistulpf.spring.factory;

import com.bistulpf.spring.annotation.*;
import com.bistulpf.spring.utils.ClassUtil;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class AnnotationBeanFactory {



    public static ConcurrentHashMap<String,Object> beans=new ConcurrentHashMap<>();

    //需要扫描的包路径
    static  String  packageName="com.bistulpf.spring" ;


    static {
        try{
            initBean() ;
         }catch (Exception e){
            e.printStackTrace();
         }
     }


    public  static void initBean() throws Exception{
        //1 使用java的反射机制扫包 获取包下所有类
        List<Class<?>> classes= ClassUtil.getClasses(packageName);
        //2 判断类上面是否存在注入bean的注解
        ConcurrentHashMap<String,Object> classExistAnnotation= findClassAnnotation(classes);
        if(classExistAnnotation==null||classExistAnnotation.isEmpty()){
            throw	new Exception("该包下没有任何类使用注解");
        }

    }

    public  static ConcurrentHashMap<String,Object> findClassAnnotation(List<Class<?>> classes) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
        creatCommonBean(classes) ;
        setAttributeToBean(classes) ;
        setProxyBean(classes) ;
        return beans;
    }

    //创建普通的JavaBean实例
    public static  ConcurrentHashMap<String,Object> creatCommonBean(List<Class<?>> classes) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        for(Class<?> classInfo:classes){
            //service 注解
            Service service=classInfo.getAnnotation(Service.class);
            if(service !=null){
                //获取注解里面的值
                String  value=service.value();
                //判断value是否为空
                if("".equals(value)){
                    //bean id 默认类名首字母小写
                    //String className=classInfo.getSimpleName();
                    String className=classInfo.getInterfaces()[0].getSimpleName();
                    String beanId=toLowerCaseFirstOne(className);
                    beans.put(beanId, newInstance(classInfo));
                }else{
                    beans.put(value, newInstance(classInfo));
                }
                continue;
            }
            //Resposition注解
            Repository repository=classInfo.getAnnotation(Repository.class);
            if(repository !=null){
                //获取注解里面的值
                String  value=repository.value();
                //判断value是否为空
                if("".equals(value)){
                    //bean id 默认类名首字母小写
                    //String className=classInfo.getSimpleName();
                    String className=classInfo.getInterfaces()[0].getSimpleName();
                    String beanId=toLowerCaseFirstOne(className);
                    beans.put(beanId, newInstance(classInfo));
                }else{
                    beans.put(value, newInstance(classInfo));
                }
                continue;
            }
            //Componet注解
            Component component=classInfo.getAnnotation(Component.class);
            if(component !=null){
                //获取注解里面的值
                String  value=component.value();
                //判断value是否为空
                if("".equals(value)){
                    //bean id 默认类名首字母小写
                    String className=classInfo.getSimpleName();
                    String beanId=toLowerCaseFirstOne(className);
                    beans.put(beanId, newInstance(classInfo));
                }else{
                    beans.put(value, newInstance(classInfo));
                }
                continue;
            }

        }
        return beans;
    }
    //设置代理bean
    public static ConcurrentHashMap<String ,Object>  setProxyBean(List<Class<?>> classes) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {

        for(Class<?> classInfo:classes){
            Service service=classInfo.getAnnotation(Service.class);
            Transactional transactional=classInfo.getAnnotation(Transactional.class) ;
            if(service !=null&&transactional!=null){
                //获取注解里面的值
                String beanId=service.value();
                Method method=beans.get("proxyFactory").getClass().getMethod("getProxy",Object.class) ;
                //判断value是否为空
                if("".equals(beanId)){
                    //bean id 默认类名首字母小写
                    //String className=classInfo.getSimpleName();
                    String className=classInfo.getInterfaces()[0].getSimpleName();
                    beanId=toLowerCaseFirstOne(className);
                    beans.put(beanId,method.invoke(beans.get("proxyFactory"),beans.get(beanId)) );
                }else{
                    beans.put(beanId,method.invoke(beans.get("proxyFactory"),beans.get(beanId)) );
                }
            }


        }
        return beans;

    }
    //设置属性
    public static ConcurrentHashMap<String ,Object>  setAttributeToBean(List<Class<?>> classes) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

        for(Class<?> classInfo:classes){
            String beanId="" ;
            if(classInfo.getInterfaces().length>0){
                String className=classInfo.getInterfaces()[0].getSimpleName();
                 beanId=toLowerCaseFirstOne(className);
            }else{
                String className=classInfo.getSimpleName();
                beanId=toLowerCaseFirstOne(className);
            }

            if(beans.get(beanId)==null){ continue;}

            Field[] fields = beans.get(beanId).getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String fieldType=field.getGenericType().toString();
                if(field.isAnnotationPresent(Autowired.class)){
                    Autowired autowired=field.getAnnotation(Autowired.class);
                    String value=autowired.value() ;
                    if("".equals(value)){
                        String simpleName=getAttributeTypeSimpleName(fieldType) ;
                        String attributeTypeName=toLowerCaseFirstOne(simpleName) ;
                        field.set(beans.get(beanId),beans.get(attributeTypeName));
                    }else{
                        field.set(beans.get(beanId),beans.get(value));
                    }

                }

            }


        }
        return beans;

    }

    public static Object newInstance(Class<?> classInfo) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException{
        return classInfo.newInstance();
    }

    // 首字母转小写
    public static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
    }
    //获取属性的类型的简单名称
    public static String getAttributeTypeSimpleName(String s) {
            String[] array=s.split("\\.") ;
            if(array.length>0){
                return array[array.length-1] ;
            }
            return "" ;
    }

}




